package com.davfx.restream;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;

import com.davfx.httpnio.HttpClient;
import com.davfx.httpnio.HttpResponse;
import com.davfx.httpnio.HttpServer;
import com.davfx.util.Log;

final class Inbound implements HttpClient.RawHttpResponseHandler {
	
	private static final long STOP_TIMEOUT = 1 * 60 * 1000L;
	
	private final Runnable closeHandler;
	private HttpResponse response = null;
	private final List<HttpServer.Response> outbounds = new LinkedList<HttpServer.Response>();
	private long timeout = -1;
	private HttpClient.Connection connection;
	private Recorder recorder = null;
	
	private final Database database;
	
	public Inbound(Runnable closeHandler, Database database) {
		this.closeHandler = closeHandler;
		this.database = database;
	}
	
	void set(HttpClient.Connection connection) {
		this.connection = connection;
	}
	
	public void add(HttpServer.Response outbound) {
		outbounds.add(outbound);
		Log.log(outbounds.size() + " outbounds");
		if (response != null) {
			outbound.write(response);
		}
		timeout = -1;
	}
	
	public void remove(HttpServer.Response outbound) {
		outbounds.remove(outbound);
		if (outbounds.isEmpty()) {
			Log.log("No more outbounds");
			timeout = System.currentTimeMillis() + STOP_TIMEOUT;
		}
	}
	
	private void doClose() {
		if (recorder != null) {
			recorder.closed();
		}
		for (HttpServer.Response r : outbounds) {
			r.close();
		}
		closeHandler.run();
	}
	
	@Override
	public void closed() {
		doClose();
	}
	
	@Override
	public void failed(IOException e) {
		doClose();
	}
	
	@Override
	public void handle(HttpResponse response) {
		recorder = new Recorder(database, System.currentTimeMillis(), response);
		this.response = response;
		for (HttpServer.Response r : outbounds) {
			r.write(response);
		}
	}
	
	@Override
	public void handle(ByteBuffer content) {
		if (timeout >= 0) {
			Log.log("Checking timeout: " + (timeout - System.currentTimeMillis()));
			if (System.currentTimeMillis() > timeout) {
				connection.close();
				doClose();
				return;
			}
		}
		for (HttpServer.Response r : outbounds) {
			r.write(content.duplicate());
		}
		recorder.handle(content);
	}
}
